# Copyright (c) 2021-2023 Alibaba Cloud Computing Ltd.
# SPDX-License-Identifier: MulanPSL-2.0

import re  
import os  
import logging

from agent.common.system import sysCommand
from agent.domain.base import BaseDomain
from agent.common.tools import ConfigFile

logger = logging.getLogger('common')

class Sysctl(BaseDomain):
    __domain__ = "sysctl"
    
    def __init__(self):
        super().__init__(domain_name = self.__domain__)
        
        _sysctl_config_path = "/etc/sysctl.conf"
        if not os.path.exists(_sysctl_config_path):
            logger.error("sysctl config file {} is not exists".format(_sysctl_config_path))
            raise Exception("sysctl config file {} is not exists".format(_sysctl_config_path))
    
        else:
            try:
                all_sysctl = sysCommand("sysctl -a",log=False)
                self.available_param = [re.search(r"^(.+)\s*=\s*.+", i).group(1).strip() \
                                        for i in all_sysctl.split('\n') \
                                        if re.search(r"^(.+)\s*=\s*.+", i)]
            except Exception as e:
                logger.error("fail to get all sysctl parameters: {}".format(e))
                self.available_param = []
            
            logger.debug("available sysctl: {}".format(self.available_param))
            self.config_file = ConfigFile(_sysctl_config_path)

    def vaild_param(self, param_name):
        return param_name in self.available_param
    
    def set_value(self, param_name:str, param_value):
        if type(param_value) is str and not param_value.startswith("'"):
            param_value = "'" + param_value
        
        if type(param_value) is str and not param_value.endswith('\''):
            param_value = param_value + "'"
        
        if param_value == "":
            raise Exception("The parameter value is empty")
        
        sysCommand("sysctl -w {param_name}={param_value} >> /etc/sysctl.conf".format(
            param_name = param_name,
            param_value = param_value
        ))
        
    def get_value(self, param_name:str):
        return sysCommand("sysctl -n {param_name}".format(
            param_name = param_name
        ))
    
    def post_setting(self):
        self.config_file.removeDuplicate()